home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / kernel / stmain.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  9KB  |  351 lines

  1. #if (CHIP == M68000)
  2. /* This file contains the main program of MINIX for the Atari ST.
  3.  * The routine main() initializes the system and starts the ball
  4.  * rolling by setting up the proc table, interrupt vectors, and
  5.  * scheduling each task to run to initialize itself.
  6.  * 
  7.  * The entries into this file are:
  8.  *   main:        MINIX main program
  9.  *   none:        called for an interrupt to an unused vector
  10.  *   rupt:        called for an unexpected interrupt (async)
  11.  *   trap:        called for an unexpected trap (synchronous)
  12.  *   panic:        abort MINIX due to a fatal error
  13.  */
  14.  
  15. #include "kernel.h"
  16. #include <signal.h>
  17. #include <minix/config.h>
  18. #include <minix/callnr.h>
  19. #include <minix/com.h>
  20. #include "proc.h"
  21.  
  22. static void initst();
  23. void panic();
  24. void mdiint();
  25.  
  26. #define SIZES              8    /* sizes array has 8 entries */
  27.  
  28. /*===========================================================================*
  29.  *                                   main                                    * 
  30.  *===========================================================================*/
  31. PUBLIC void main()
  32. {
  33. /* Start the ball rolling. */
  34.  
  35.   register struct proc *rp;
  36.   register int t;
  37.   register vir_clicks size;
  38.   register phys_clicks base;
  39.   reg_t ktsb;
  40.  
  41.   initst();
  42.  
  43.   /* Clear the process table.
  44.    * Set up mappings for proc_addr() and proc_number() macros.
  45.    */
  46.   for (rp = BEG_PROC_ADDR, t = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++t) {
  47.         rp->p_flags = P_SLOT_FREE;
  48.         rp->p_nr = t;           /* proc number from ptr */
  49.         (pproc_addr + NR_TASKS)[t] = rp;        /* proc ptr from number */
  50.   }
  51.  
  52.   size = sizes[0] + sizes[1];    /* kernel text + data size */
  53.   base = size;            /* end of kernel */
  54.  
  55.   ktsb = ((reg_t) t_stack + (ALIGNMENT - 1)) & ~((reg_t) ALIGNMENT - 1);
  56.   for (t = -NR_TASKS; t < 0; t++) {    /* for all drivers */
  57.     rp = proc_addr(t);
  58.     rp->p_flags = 0;
  59.     ktsb += tasktab[t+NR_TASKS].stksize;
  60.     rp->p_reg.sp = ktsb;
  61.     rp->p_splow = rp->p_reg.sp;
  62.     rp->p_reg.pc = (reg_t) tasktab[t + NR_TASKS].initial_pc;
  63.     if (!isidlehardware(t)) {
  64.         lock_ready(rp);    /* IDLE, HARDWARE neveready */
  65.         rp->p_reg.psw = 0x2200;    /* S-BIT, SPL2 */
  66.     } else {
  67.         rp->p_reg.psw = 0x0200;    /* SPL2 */
  68.     }
  69.     rp->p_map[T].mem_len  = sizes[0];
  70. /*    rp->p_map[T].mem_phys = 0; */
  71.     rp->p_map[D].mem_len  = sizes[1]; 
  72.     rp->p_map[D].mem_phys = sizes[0];
  73. /*    rp->p_map[S].mem_len  = 0; */
  74.     rp->p_map[S].mem_phys = size;
  75. /*    rp->p_map[T].mem_vir  = rp->p_map[T].mem_phys; */
  76.     rp->p_map[D].mem_vir  = rp->p_map[D].mem_phys;
  77.     rp->p_map[S].mem_vir  = rp->p_map[S].mem_phys;
  78.   }
  79.  
  80.   rp = proc_addr(HARDWARE);
  81.   rp->p_map[D].mem_len  = ~0;    /* maximum size */
  82.   rp->p_map[D].mem_phys = 0;
  83.   rp->p_map[D].mem_vir  = 0;
  84.  
  85.   for (t = 0; t <= LOW_USER; t++) {
  86.     rp = proc_addr(t);
  87.     rp->p_flags = 0;
  88.     lock_ready(rp);
  89.     rp->p_reg.psw = (reg_t)0x0200;    /* no S-BIT, SPL2 */
  90.     rp->p_reg.pc = (reg_t) ((long)base << CLICK_SHIFT);
  91.     size = sizes[2*t + 2];
  92.     rp->p_map[T].mem_len  = size;
  93.     rp->p_map[T].mem_phys = base;
  94.     base += size;
  95.     size = sizes[2*t + 3];
  96.     rp->p_map[D].mem_len  = size;
  97.     rp->p_map[D].mem_phys = base;
  98.     base += size;
  99.     rp->p_map[S].mem_len  = 0;
  100.     rp->p_map[S].mem_phys = base;
  101.     rp->p_map[T].mem_vir  = rp->p_map[T].mem_phys;
  102.     rp->p_map[D].mem_vir  = rp->p_map[D].mem_phys;
  103.     rp->p_map[S].mem_vir  = rp->p_map[S].mem_phys;
  104.   }
  105.  
  106.   bill_ptr = proc_addr(HARDWARE);    /* it has to point somewhere */
  107.   lock_pick_proc();
  108.  
  109.   /* go back to assembly code to start running the current process. */
  110. }
  111.  
  112.  
  113. /*===========================================================================*
  114.  *                              none, rupt, trap                             * 
  115.  *===========================================================================*/
  116. PUBLIC void none()
  117. {
  118.   panic("Nonexisting interrupt. Vector =", proc_ptr->p_trap);
  119. }
  120.  
  121. PUBLIC void rupt()
  122. {
  123.   panic("Unexpected interrupt.  Vector =", proc_ptr->p_trap);
  124. }
  125.  
  126.  
  127. PUBLIC void trap()
  128. {
  129.   register t;
  130.   register struct proc *rp;
  131.   static char vecsig[] = {
  132.     0, 0, SIGSEGV, SIGBUS, SIGILL, SIGILL, SIGILL, SIGABRT,
  133.     SIGILL, SIGTRAP, SIGEMT, SIGFPE, SIGSTKFLT
  134.   };
  135.  
  136.   rp = proc_ptr;
  137.   t = rp->p_trap;
  138.   if (rp->p_reg.psw & 0x2000) panic("trap via vector", t);
  139.   if (t >= 0 && t < sizeof(vecsig)/sizeof(vecsig[0]) && vecsig[t]) {
  140.     t = vecsig[t];
  141.   } else {
  142.     printf("\nUnexpected trap.  Vector = %d\n", t);
  143.     printf("This may be due to accidentally including\n");
  144.     printf("a non-MINIX library routine that is trying to make a system call.\n");
  145.     t = SIGILL;
  146.   }
  147.   if (t != SIGSTKFLT) {    /* DEBUG */
  148.     printf("sig=%d to pid=%d at pc=%X\n",
  149.         t, rp->p_pid, rp->p_reg.pc);
  150.     dump();
  151.   }
  152.   cause_sig(proc_number(rp), t);
  153. }
  154.  
  155. PUBLIC void checksp()
  156. {
  157.   register struct proc *rp;
  158.   register phys_bytes ad;
  159.  
  160.   rp = proc_ptr;
  161.   /* if a user process is is supervisor mode don't check stack */
  162.   if ((rp->p_nr >= 0) && (rp->p_reg.psw & 0x2000)) return;
  163.   if (rp->p_reg.sp < rp->p_splow)
  164.     rp->p_splow = rp->p_reg.sp;
  165.   if (rp->p_map[S].mem_len == 0)
  166.     return;
  167.   ad = (phys_bytes)rp->p_map[S].mem_phys;
  168.   ad <<= CLICK_SHIFT;
  169.   if ((phys_bytes)rp->p_reg.sp > ad)
  170.     return;
  171.   /*
  172.    * Stack violation.
  173.    */
  174.   ad = (phys_bytes)rp->p_map[D].mem_phys;
  175.   ad += (phys_bytes)rp->p_map[D].mem_len;
  176.   ad <<= CLICK_SHIFT;
  177.   if ((phys_bytes)rp->p_reg.sp < ad + CLICK_SIZE)
  178.     printf("Stack low (pid=%d,pc=%X,sp=%X,end=%X)\n",
  179.         rp->p_pid, (long)rp->p_reg.pc,
  180.         (long)rp->p_reg.sp, (long)ad);
  181.   rp->p_trap = 12;    /* fake trap causing SIGSTKFLT */
  182.   trap();
  183. }
  184.  
  185. /*===========================================================================*
  186.  *                                   panic                                   * 
  187.  *===========================================================================*/
  188. PUBLIC void panic(s,n)
  189. char *s;
  190. int n; 
  191. {
  192. /* The system has run aground of a fatal error.  Terminate execution.
  193.  * If the panic originated in MM or FS, the string will be empty and the
  194.  * file system already syncked.  If the panic originates in the kernel, we are
  195.  * kind of stuck. 
  196.  */
  197.  
  198.   if (*s != 0) {
  199.     printf("\nKernel panic: %s",s); 
  200.     if (n != NO_NUM) printf(" %d", n);
  201.     printf("\n");
  202.   }
  203.   dump();
  204.   printf("\nPush RESET button\n");
  205.   for (;;)
  206.     ;
  207. }
  208.  
  209. /*
  210.  * Atari ST specific initialization.
  211.  */
  212.  
  213. #include "staddr.h"
  214. #include "stacia.h"
  215. #include "stmfp.h"
  216. #include "stsound.h"
  217. #include "stvideo.h"
  218.  
  219. /*===========================================================================*
  220.  *                                   initst                                   * 
  221.  *===========================================================================*/
  222. PRIVATE void initst()
  223. {
  224.   long ad;
  225.  
  226.   /*
  227.    * both 8-bit ports of the sound chip are configured for output
  228.    */
  229.   SOUND->sd_selr = YM_MFR;
  230.   SOUND->sd_wdat = PA_OUT|PB_OUT;
  231.   /*
  232.    * init port A (Note: low 3 bits inverted)
  233.    */
  234.   SOUND->sd_selr = YM_IOA;
  235.   SOUND->sd_wdat = SOUND->sd_rdat | PA_PSTROBE;
  236.   /*
  237.    * initialize MFP
  238.    */
  239.   MFP->mf_ierb |= (IB_DINT|IB_AINT|IB_TIMC|IB_PBSY);
  240.   MFP->mf_imrb |= (IB_DINT|IB_AINT|IB_TIMC|IB_PBSY);
  241.   MFP->mf_iera |= (IA_RRDY|IA_RERR|IA_TRDY|IA_TERR);
  242.   MFP->mf_imra |= (IA_RRDY|IA_RERR|IA_TRDY|IA_TERR);
  243.   MFP->mf_vr = V_INIT;
  244.   /*
  245.    * The following code is needed if TOS is not in ROM.
  246.    * It is harmless for more modern systems.
  247.    */
  248.   ad = *((long *)0x042E);    /* TOS variable 'phystop' */
  249.   ad -= 0x8000L;        /* size of VIDEO memory */
  250.   *((long *)0x0436) = ad;    /* TOS variable '_memtop' */
  251.   VIDEO->vd_ramm = (char)(ad >> 8);
  252.   VIDEO->vd_ramh = (char)(ad >> 16);
  253. }
  254.  
  255. /*===========================================================================*
  256.  *                aciaint                         *
  257.  *===========================================================================*/
  258. PUBLIC void aciaint()
  259. {
  260.   if (KBD->ac_cs & A_IRQ)
  261.     kbdint();
  262.   if (MDI->ac_cs & A_IRQ)
  263.     mdiint();
  264. }
  265.  
  266. /*===========================================================================*
  267.  *                temporary stuff                     *
  268.  *===========================================================================*/
  269.  
  270. PUBLIC void fake_int(s, t)
  271. char *s;
  272. int t;
  273. {
  274.   if (t != 0x03)
  275.     printf("Fake interrupt handler for %s. trap = %02x\n", s, t);
  276. }
  277.  
  278. PUBLIC void timint(t)
  279. int t;
  280. {
  281.   fake_int("timint", t);
  282. }
  283.  
  284. PUBLIC void mdiint(t)
  285. int t;
  286. {
  287.     int code;
  288.     int i;
  289.  
  290.     for (i = 0; i < 200; i++) 
  291.         if (MDI->ac_cs & A_IRQ)
  292.         {
  293.             code = MDI -> ac_da;
  294.             i = 0;